#include"../source/socket.hpp"
#include"../source/server.hpp"
#include"../source/acceptor.hpp"

void CloseHandler(Channel*channel){
    // std::cout<<"close: "<<channel->FD()<<std::endl;
    DLOG("close:%d",channel->FD());
    channel->Remove();//移除监控，出错了就把这个channel给移除了
    delete channel;
}
//传channel或者传fd都可以，反正能获取到就行
void ReadHandler(Channel*channel){
    char buffer[1024];
    ssize_t ret=recv(channel->FD(),buffer,sizeof(buffer)-1,0);
    if(ret<=0){
        DLOG("关闭");
        return CloseHandler(channel);//关闭并释放
    }
    channel->EnableWrite();
    // std::cout<<buffer<<std::endl;
    DLOG("%s",buffer);
}
void WriteHandler(Channel*channel){
    std::string anything ="你好啊";
    ssize_t ret=send(channel->FD(),anything.c_str(),anything.size(),0);
    if(ret<0){
        return CloseHandler(channel);//关闭并释放
    }
    // DLOG("aaaa");
    // std::cout<<"event: "<<channel->Events()<<"||"<<channel->Revent()<<"||"<<EPOLLOUT<<std::endl;
    channel->DisableWrite();//关闭写监控
    // std::cout<<"event: "<<channel->Events()<<"||"<<channel->Revent()<<"||"<<EPOLLOUT<<std::endl;

}

void ErrorHandler(Channel*channel){
    std::cout<<"error:"<<channel<<std::endl;
    return CloseHandler(channel);//关闭并释放
}
void EventHandler(Channel*channel,EventLoop* loop,uint64_t timerfd){
    // std::cout<<"有了一个事件"<<std::endl;
    loop->TimerRefresh(timerfd);
}
void Acceptor(Channel* listen_channel,EventLoop*loop){
    int fd=listen_channel->FD();
    int newfd=accept(fd,NULL,NULL);
    if(newfd<0) return;

    uint64_t timerfd=rand()%10000;
    Channel* channel =new Channel(newfd,loop);
    channel->SetReadCallback(std::bind(ReadHandler,channel));//为通信套接字设置可读事件的回调函数
    channel->SetWriteCallback(std::bind(WriteHandler,channel));//为通信套接字设置可写事件的回调函数
    channel->SetErrorCallback(std::bind(ErrorHandler,channel));//为通信套接字设置错误事件的回调函数
    channel->SetCloseCallback(std::bind(CloseHandler,channel)); //为通信套接字设置关闭事件的回调函数
    channel->SetEventCallback(std::bind(EventHandler,channel,loop,timerfd));//为通信套接字设置任意事件的回调函数------有问题
    
    //非活跃连接的超时释放操作,10s后关闭连接
    //注意：定时销毁任务，必须在启动读事件之前，因为有可能启动了事件监控后，立即就有了事件，但是这时候还没有任务
    //所以监控到任意事件的时候，就要刷新定时时间
    loop->TimerAdd(timerfd,10,std::bind(CloseHandler,channel));

    channel->EnableRead();//开始可读
}
int main()
{   
    srand(time(NULL));
    //Poller poller;
    EventLoop loop;
    Socket listen_socket;   
    listen_socket.CreateServer(8081);
    //为监听套接字创建一个Channel进行事件的管理，以及事件的处理
    Channel channel(listen_socket.Get_fd(),&loop);
    channel.SetReadCallback(std::bind(Acceptor,&channel,&loop));//在回调中，获取新连接，为新连接创建Channel并添加监控
    channel.EnableRead();//启动可读事件监控
    while(1){
        loop.Start();

        // std::vector<Channel*> actives;
        // poller.Poll(&actives);
        // for(auto &a:actives){
        //     a->HandleEvent();
        // }



        // int newfd=listen_socket.Accept();
        // if(newfd<0){
        //     DLOG("accept failed");
        //     continue;
        // }
        // Socket cli_socket(newfd);
        // char buffer[1024]={0};
        // int ret=cli_socket.Recv(buffer,sizeof(buffer)-1);
        // if(ret<0){
        //     cli_socket.Close();
        //     continue;
        // }
        // cli_socket.Send(buffer,ret);
        // cli_socket.Close();
    }
    listen_socket.Close();
    return 0;
}